# Modify Axis
library(ggplot2)
library(readr)
chic <- read_csv("ggplot2/ggModify/chicago-nmmaps.csv")

# 1. 添加坐标轴标题
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") #或者用xlab()和ylab()

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  # expression()可以表达数学符号
  labs(x = "Year", y = expression(paste("Temperature (", degree ~ "F)")))


# 2. 增加轴和轴标题之间的空间
# Theme()是修改特定主题元素(文本、标题、框、符号、背景等)的必要命令。

# vjust指的是垂直对齐，它的范围通常在0和1之间，但也可以指定该范围之外的值。
# 注意，即使我们水平移动y轴上的轴标题，我们也需要指定vjust(从标签的角度来看，这是正确的)。
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title.x = element_text(vjust = 0, size = 14),
        axis.title.y = element_text(vjust = 1, size = 14))

# 你也可以通过指定两个文本元素的边距来改变距离:
#   margin()对象中的标签t和r分别指代top和right。
#   你还可以将这四个边距指定为margin(t, r, b, l)。
#   请注意，我们现在必须更改右边边距来修改y轴上的空间，而不是底部边距。
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title.x = element_text(margin = margin(t = 10), size = 14),
        axis.title.y = element_text(margin = margin(r = 10), size = 14))

ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title.x = element_text(vjust = 0, size = 14),
        axis.title.y = element_text(vjust = 1, size = 14),
        axis.title.x.top = element_text(vjust = 1, size = 14),
        axis.title.y.right = element_text(vjust = 0, size = 14))


# 3. 改变轴标题的美学

# 3.1 使用theme()函数并修改元素axis.title.x和axis.title.y。
#   例如，在element_text()中，我们可以覆盖大小、颜色和外观的默认值。
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  # face参数可用于使字体加粗或倾斜。
  theme(axis.title = element_text(size = 14, color = "firebrick", face = "italic"))


ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.title.x = element_text(size = 14, color = "sienna"),
        axis.title.y = element_text(size = 14, color = "orangered"))

# 3.2 还可以使用axis更改坐标轴文本(这里是数字)的外观。
#   通过文本和/或附属元素axis.text.x和axis.text.y:
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.text.x = element_text(size = 12, color = "sienna"),
        axis.text.y = element_text(size = 12, color = "orangered"))

# 3.3 旋转坐标轴文本
#   指定角度可以旋转任何文本元素。
#   使用hjust和vjust你可以在水平(0 =左，1 =右)和垂直(0 =上，1 =下)调整文本的位置:
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  theme(axis.text.x = element_text(size = 12, color = "sienna", angle = 45, hjust = 1, vjust = 1))

# 3.4 删除坐标轴标题
# 可以使用theme_blank()，但是通过labs()(或xlab())中删除标签要更简单。
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = NULL, y = "")

# 3.5 限制坐标轴范围
#   有时你想要放大到更近距离地查看一些数据。
#   你可以在不划分数据的情况下做到这一点:
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  ylim(c(0, 50))

# 或者，您可以使用scale_y_continuous(limits = c(0,50))
# 或coord_cartesian(ylim = c(0,50))。
# 前者去除范围外的所有数据点，而后者调整可见区域，类似于ylim(c(0,50))。
# 你可能会想:所以最后两者的结果是一样的。但并非如此，有一个重要的区别——比较以下两个图:

# 3.6 使图表从坐标原点开始
library(tidyverse)
chic_high <- chic %>%
  filter(temp >= 25, o3 > 20)

ggplot(chic_high, aes(x = temp, y = o3)) +
  geom_point(color = "darkcyan") +
  labs(x = "Temperature (°F) > 25", y = "Ozone > 20") +
  expand_limits(x = 0, y = 0)

# 3.7 相同比例的坐标轴
#   coord_equal()是一个坐标系统，其指定的比率表示y轴上的单位数与x轴上的单位数相等。
#   默认ratio = 1，确保x轴上的一个单位与y轴上的一个单位长度相同:
ggplot(chic, aes(x = temp, y = temp + rnorm(nrow(chic), sd = 20))) +
  geom_point(color = "sienna") +
  labs(x = "Temperature (°F)", y = "Temperature (°F) + rand noise") +
  xlim(c(0, 100)) +
  ylim(c(0, 150)) +
  coord_fixed()

# 高于1的比率会使y轴上的单位比x轴上的单位长，反之亦然:
ggplot(chic, aes(x = temp, y = temp + rnorm(nrow(chic), sd = 20))) +
  geom_point(color = "sienna") +
  labs(x = "Temperature (°F)", y = "Temperature (°F) + rand noise") +
  xlim(c(0, 100)) +
  ylim(c(0, 150)) +
  coord_fixed(ratio = 1/5)

# 3.8 固定坐标轴
#   可以固定坐标轴的长宽比，并固定x和y轴的呈现物理单位:
ggplot(chic, aes(x = temp, y = o3)) +
  geom_point() +
  labs(x = "Temperature (°F)", y = "Ozone Level") +
  scale_x_continuous(breaks = seq(0, 80, by = 20)) +
  coord_fixed(ratio = 1)

# 通过这种方式，不仅可以确保轴上的步长，还可以确保导出的图看起来与预期的一样。
# 然而，如果没有使用合适的宽高比，保存的plot可能包含很多空白:
ggplot(chic, aes(x = temp, y = o3)) +
  geom_point() +
  labs(x = "Temperature (°F)", y = "Ozone Level") +
  scale_x_continuous(breaks = seq(0, 80, by = 20)) +
  coord_fixed(ratio = 1/3) +
  theme(plot.background = element_rect(fill = "grey80"))

# 3.9 使用函数调整标签
#   比如添加单位或百分号，而不在数据中直接添加这些标签。
#   在这种情况下你可以使用一个函数:
ggplot(chic, aes(x = date, y = temp)) +
  geom_point(color = "firebrick") +
  labs(x = "Year", y = "Temperature (°F)") +
  scale_y_continuous(labels = function(x) paste0(x, "°F"))


# 4. 翻转图表
# 4.1 翻转图表是非常容易的， 使用coord_flip()。
#   当使用geom 's是用来表示分类数据时，就更有意义了，例如box或如下示例所示的whiskers图:
ggplot(chic, aes(x = season, y = o3)) +
  geom_boxplot(fill = "indianred") +
  labs(x = "Season", y = "Ozone") +
  coord_flip()


# 4.2 反转轴（180度颠倒）
#   也可以分别使用scale_x_reverse()或scale_y_reverse()轻松地反转一个轴:
ggplot(chic, aes(x = date, y = temp, color = o3)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  scale_y_reverse()

# 4.3 转化轴（刻度转换）
#   使用scale_y_log10()或scale_y_sqrt()来转换默认的线性映射。
#   例如，这里有一个log10转换的轴(在这种情况下引入了NA，所以要小心):
ggplot(chic, aes(x = date, y = temp, color = o3)) +
  geom_point() +
  labs(x = "Year", y = "Temperature (°F)") +
  scale_y_log10(lim = c(0.1, 100))

# 5. 环化图
# 5.1 也可以通过调用coord_polar()将坐标系统环化。
chic %>%
  dplyr::group_by(season) %>%
  dplyr::summarize(o3 = median(o3)) %>%
  ggplot(aes(x = season, y = o3)) +
    geom_col(aes(fill = season), color = NA) +
    labs(x = "", y = "Median Ozone Level") +
    coord_polar() +
    guides(fill = FALSE)

# 这个坐标系统也允许绘制饼图:

chic_sum <-
  chic %>%
  dplyr::mutate(o3_avg = median(o3)) %>%
  dplyr::filter(o3 > o3_avg) %>%
  dplyr::mutate(n_all = n()) %>%
  dplyr::group_by(season) %>%
  dplyr::summarize(rel = n() / unique(n_all))

ggplot(chic_sum, aes(x = "", y = rel)) +
  geom_col(aes(fill = season), width = 1, color = NA) +
  labs(x = "", y = "Proportion of Days Exceeding\nthe Median Ozone Level") +
  coord_polar(theta = "y") +
  scale_fill_brewer(palette = "Set1", name = "Season:") +
  theme(axis.ticks = element_blank(),
        panel.grid = element_blank())

# 建议查看相同代码在笛卡尔坐标系下的结果，以理解coord_polar()和theta背后的逻辑:
ggplot(chic_sum, aes(x = "", y = rel)) +
  geom_col(aes(fill = season), width = 1, color = NA) +
  labs(x = "", y = "Proportion of Days Exceeding\nthe Median Ozone Level") +
  #coord_polar(theta = "y") +
  scale_fill_brewer(palette = "Set1", name = "Season:") +
  theme(axis.ticks = element_blank(),
        panel.grid = element_blank())
